home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / system / serialxx.zip / SERIALA.ASM < prev   
Assembly Source File  |  1989-12-19  |  8KB  |  307 lines

  1. ; Copyright Prototronics
  2. ; Totem Lake P.O. 8117
  3. ; Kirkland, Washington 98034
  4.  
  5. ; Joe Huffman 
  6. ; September 19, 1989
  7. ; (206) 820-1972
  8.  
  9.         include macros.asm
  10.  
  11. c_public serial_port_init, serial_port_term
  12.  
  13.         begdata
  14.  
  15. serial_port_buffer struc        ;DON'T change this structure without looking
  16.                                 ;at the corresponding c++ code.  Structures
  17. send_buffer     dd      ?       ;must match.
  18. send_head_p     dd      ?
  19. send_tail_p     dd      ?
  20. receive_buffer  dd      ?
  21. receive_head_p  dd      ?
  22. receive_tail_p  dd      ?
  23. send_bytes      dw      ?
  24. receive_bytes   dw      ?
  25. buf_size        dw      ?
  26. old_int_vec     dd      ?
  27. com_port_addr   dw      ?
  28. int_number      db      ?
  29. eoi_indicator   db      ?
  30. serial_port_buffer ends
  31.  
  32. com1_buffer_struc_p     dd      ?
  33. com2_buffer_struc_p     dd      ?
  34.  
  35.         enddata
  36.  
  37. NO_INTERRUPT            equ     2       ;Also define in c++ code. Must be same.
  38.  
  39. I8259_END_OF_INTR_PORT  equ     20h
  40.  
  41. ;Interrupt enable bits.
  42. REC_DATA_INTR           equ     1
  43. TRAN_DATA_INTR          equ     2
  44. REC_STATUS_INTR         equ     4
  45.  
  46. ;Interrupt ID defines.
  47. INTR_REC_DATA           equ     4       ;Received data availiable.
  48. INTR_TRAN_EMPTY         equ     2       ;Transmit holding register is empty.
  49.  
  50. REC_REG_OFFSET          equ     0
  51. TRAN_REG_OFFSET         equ     0
  52. INTR_ENABLE_OFFSET      equ     1
  53. INTR_IDENT_OFFSET       equ     2
  54.  
  55. COM1_INT        equ     0ch
  56. COM2_INT        equ     0bh
  57.  
  58.         begcode serialasm
  59.  
  60. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  61. ;Service the interrupt.
  62. ;September 19, 1989
  63. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  64. com2_server:
  65.         push    si
  66.         push    ds
  67.  
  68.         mov     si,dgroup
  69.         mov     ds,si
  70.         lds     si,com2_buffer_struc_p
  71.  
  72.         jmps    com_common_server
  73.  
  74.  
  75. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  76. ;Service the interrupt.
  77. ;September 19, 1989
  78. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  79. com1_server:
  80.         push    si
  81.         push    ds
  82.  
  83.         mov     si,dgroup
  84.         mov     ds,si
  85.         lds     si,com1_buffer_struc_p
  86.  
  87. com_common_server:
  88.         sti
  89.  
  90.         push    ax
  91.         push    dx
  92.         push    di
  93.         push    es
  94.  
  95. which_interrupt:
  96.         mov     dx,com_port_addr [si]
  97.         mov     di,INTR_IDENT_OFFSET
  98.         add     dx,di                   ;Figure out which interrupt this is.
  99.         in      al,dx                   ;AL has the interrupt id code.
  100.         sub     dx,di                   ;Leave dx with port address.
  101.  
  102.         test    al,INTR_REC_DATA        ;Is there data waiting?
  103.         jnz     data_waiting
  104.  
  105.         test    al,INTR_TRAN_EMPTY      ;Read to send data?
  106.         jnz     send_byte
  107.  
  108. unknown_interrupt:
  109.         jmp     short all_done
  110.  
  111.  
  112. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  113. ;The send server.
  114. send_byte:
  115.         mov     ax,send_bytes[si]
  116.         or      ax,ax                   ;Any bytes to send?
  117.         jnz     do_send
  118.  
  119.         add     dx,INTR_ENABLE_OFFSET   ;No bytes to send so turn off
  120.         in      al,dx                   ;transmit interrupts.
  121.         and     al,NOT TRAN_DATA_INTR
  122.         out     dx,al
  123.  
  124.         jmp     short server_done
  125.  
  126. do_send:
  127.         les     di,send_tail_p [si]
  128.         mov     al,es:[di]
  129.  
  130. if TRAN_REG_OFFSET                      ;If offset is non-zero
  131.         add     dx,TRAN_REG_OFFSET
  132. endif
  133.         out     dx,al
  134.  
  135.         dec     send_bytes [si]
  136.  
  137.         inc     di                      ;Pointer to send_buffer.
  138.         mov     ax,di
  139.         sub     ax,word ptr send_buffer [si]
  140.         cmp     ax,buf_size [si]
  141.         jb      send_done               ;No wrap around.
  142.  
  143.         mov     di,word ptr send_buffer [si]
  144.  
  145. send_done:
  146.         mov     word ptr send_tail_p[si],di
  147.         jmp     short server_done
  148.  
  149.  
  150. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  151. ;The receive server.
  152. data_waiting:
  153. if REC_REG_OFFSET
  154.         add     dx,REC_REG_OFFSET
  155. endif
  156.         in      al,dx           ;AL has the input data.
  157.  
  158.         mov     di,receive_bytes [si]
  159.         cmp     di,buf_size [si]
  160.  
  161.         jae     server_done     ;Overflow.
  162.  
  163.         inc     di              ;Bytes received.
  164.         mov     receive_bytes [si],di
  165.  
  166.         les     di,receive_head_p [si]
  167.         cld
  168.         stosb
  169.  
  170.         mov     ax,di           ;Receiver head_p
  171.         mov     dx,word ptr receive_buffer [si]
  172.         sub     ax,dx
  173.         cmp     ax,buf_size [si]        ;Wrap around?
  174.  
  175.         jb      receive_done
  176.         mov     di,dx                   ;receiver_buffer to di.
  177.  
  178. receive_done:
  179.         mov     word ptr receive_head_p [si],di
  180.  
  181. server_done:
  182.         jmp     short which_interrupt   ;Check to see if another interrupt had
  183.                                         ;occurred.
  184.  
  185. all_done:
  186.         mov     al,eoi_indicator [si]   ;Enable this interrupt to occur again.
  187.         out     I8259_END_OF_INTR_PORT,al
  188.  
  189.         pop     es
  190.         pop     di
  191.         pop     dx
  192.         pop     ax
  193.         pop     ds
  194.         pop     si
  195.         iret
  196.  
  197.  
  198. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  199. ;Install the interrupt handler.  Return NO_INTERRUPT if unable 
  200. ;to install the interrupt.
  201. ;September 20, 1989
  202. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  203. func    serial_port_init
  204.  
  205.         push    bp
  206.         mov     bp,sp
  207.         push    si
  208.  
  209. if LPTR
  210.         les     si,P[bp]
  211. else
  212.         mov     si,P[bp]
  213. ife ESeqDS
  214.         mov     ax,ds
  215.         mov     es,ax
  216. endif
  217. endif
  218.  
  219.         mov     ah,35h                  ;Get an interrupt.
  220.  
  221.         push    es
  222.         mov     al,es:int_number [si]   ;The interrupt to get from DOS.
  223.         int     21h
  224.  
  225.         mov     ax,es
  226.         pop     es
  227.  
  228.         mov     word ptr es:(old_int_vec + 2)[si],ax
  229.         mov     word ptr es:old_int_vec[si],bx
  230.  
  231.         mov     bx,cs                   ;Segment of int service routine.
  232.  
  233.         mov     dx,offset com1_server
  234.         mov     al,es:int_number [si]   ;The interrupt to install.
  235.         cmp     al,COM1_INT
  236.         jz      install_1
  237.  
  238.         cmp     al,COM2_INT
  239.         jz      install_2
  240.  
  241.         mov     ax,NO_INTERRUPT         ;Not com1 and not com2.  Ignore it.
  242.         jmps    done                    ;return unable to install interrupt.
  243.  
  244. install_2:
  245.         mov     dx,offset com2_server
  246.         mov     word ptr com2_buffer_struc_p,si
  247.         mov     word ptr com2_buffer_struc_p + 2,es
  248.         jmps    install
  249.  
  250. install_1:
  251.         mov     word ptr com1_buffer_struc_p,si
  252.         mov     word ptr com1_buffer_struc_p + 2,es
  253.  
  254. install:
  255.         push    ds
  256.         mov     ds,bx                   ;ds:dx points to server.
  257.         mov     ah,25h                  ;al has int number.
  258.         int     21h
  259.         pop     ds
  260.  
  261.         clr     ax                      ;Return 0.
  262.  
  263. done:
  264. if ESeqDS
  265.         mov     bx,ds
  266.         mov     es,bx
  267. endif
  268.         pop     si
  269.         pop     bp
  270.         ret
  271.  
  272. c_endp  serial_port_init
  273.  
  274. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  275. ;Uninstall the interrupt.
  276. ;September 19, 1989
  277. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  278. func    serial_port_term
  279.         push    bp
  280.         mov     bp,sp
  281.         push    si
  282.         push    ds
  283.  
  284. if LPTR
  285.         lds     si,P[bp]
  286. else
  287.         mov     si,P[bp]
  288. endif
  289.  
  290.         mov     ah,25h                  ;Install an interrupt.
  291.         mov     al,es:int_number [si]
  292.  
  293.         lds     dx,old_int_vec [si]     ;The old interrupt.
  294.  
  295.         int     21h                     ;Do the (un)install.
  296.  
  297.         pop     ds
  298.         pop     si
  299.         pop     bp
  300.         ret
  301.  
  302. c_endp  serial_port_term
  303.  
  304.         endcode serialasm
  305.         end
  306.  
  307.